package DESUtil

import (
	"errors"
	"crypto/des"
	"security/Base64Util"
	"bytes"
	"fmt"
)

/**
以下算法与http://tool.chacuo.net/cryptdes的ECB算法一致
与SN框架中的DESUtil的不一致之处在于,SN框架中的key生成是使用的generator生成的，带有一定随机性
SecureRandom.getInstance("SHA1PRNG","SUN");
secureRandom.setSeed(strKey.getBytes());//此处strKey可以任意长度
Key  key = _generator.generateKey();
而此处的key必须指定初始值
Key key = new SecretKeySpec(strKey.getBytes(), "DES");//此处strKey必须为8位
因此导致了框架性兼容问题
*/

func PKCS5PaddingECB(ciphertext []byte, blockSize int) []byte {
	padding := blockSize - len(ciphertext)%blockSize
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(ciphertext, padtext...)
}

func PKCS5UnPaddingECB(origData []byte) []byte {
	length := len(origData)
	unpadding := int(origData[length-1])
	return origData[:(length - unpadding)]
}

func EncryptECB(data []byte, key []byte) ([]byte,error){
	if len(key) > 8 {
		key = key[:8]
	}
	block, err := des.NewCipher(key)
	if err != nil {
		return nil,err
	}
	bs := block.BlockSize()
	data = PKCS5PaddingECB(data, bs)
	if len(data)%bs != 0 {
		return nil,errors.New("EncryptDES crypto/cipher: input not full blocks")
	}
	out := make([]byte, len(data))
	dst := out
	for len(data) > 0 {
		block.Encrypt(dst, data[:bs])
		data = data[bs:]
		dst = dst[bs:]
	}
	return out,nil
}
func DecryptECB(d []byte, key []byte) ([]byte,error) {
	data := d
	//if err != nil {
	//	return "",err
	//}
	if len(key) > 8 {
		key = key[:8]
	}
	block, err := des.NewCipher(key)
	if err != nil {
		return nil,err
	}
	bs := block.BlockSize()
	if len(data)%bs != 0 {
		return nil,errors.New("DecryptDES crypto/cipher: input not full blocks")
	}
	out := make([]byte, len(data))
	dst := out
	for len(data) > 0 {
		block.Decrypt(dst, data[:bs])
		data = data[bs:]
		dst = dst[bs:]
	}
	out = PKCS5UnPaddingECB(out)
	return out,nil
}

//[golang ECB 3DES Encrypt]
func TripleEcbDesEncrypt(origData, key []byte) ([]byte, error) {
	tkey := make([]byte, 24, 24)
	copy(tkey, key)
	k1 := tkey[:8]
	k2 := tkey[8:16]
	k3 := tkey[16:]

	block, err := des.NewCipher(k1)
	if err != nil {
		return nil, err
	}
	bs := block.BlockSize()
	origData = PKCS5PaddingECB(origData, bs)

	buf1, err := EncryptECB(origData, k1)
	if err != nil {
		return nil, err
	}
	buf2, err := DecryptECB(buf1, k2)
	if err != nil {
		return nil, err
	}
	out, err := EncryptECB(buf2, k3)

	if err != nil {
		return nil, err
	}
	return out, nil
}

//[golang ECB 3DES Decrypt]
func TripleEcbDesDecrypt(crypted, key []byte) ([]byte, error) {
	tkey := make([]byte, 24, 24)
	copy(tkey, key)
	k1 := tkey[:8]
	k2 := tkey[8:16]
	k3 := tkey[16:]
	buf1, err := DecryptECB(crypted, k3)
	if err != nil {
		return nil, err
	}
	buf2, err := EncryptECB(buf1, k2)
	if err != nil {
		return nil, err
	}
	out, err := DecryptECB(buf2, k1)
	if err != nil {
		return nil, err
	}
	out = PKCS5UnPaddingECB(out)
	return out, nil
}

func EncryptStrECB(key string,ming string)(string,error){
	var mibyte,err = EncryptECB([]byte(ming),[]byte(key))
	if(err!=nil){
		return "",err
	}
	return Base64Util.EncodeMessage(mibyte),nil
}
func DecryptStrECB(key string, mi string)(string,error){
	var unbase64 = Base64Util.DecodeMessage(mi)
	var ming,err = DecryptECB(unbase64,[]byte(key))
	if(err!=nil){
		return "",err
	}
	return string(ming),nil
}

func main (){
	fmt.Println(EncryptECB([]byte("cccccccc"),[]byte("12345678")))
}
/**
JAVA代码备注

package cn.com.xbase.security.des;

import cn.com.xbase.security.base64.Base64Util;

import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;


public class DesECBUtil {

public static String encryptDES(String encryptString, String encryptKey) throws Exception {
SecretKeySpec key = new SecretKeySpec(getKey(encryptKey), "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptedData = cipher.doFinal(encryptString.getBytes());
return Base64Util.encodeMessage(encryptedData);
}


public static byte[] getKey(String keyRule) {
Key key = null;
byte[] keyByte = keyRule.getBytes();
// 创建一个空的八位数组,默认情况下为0
byte[] byteTemp = new byte[8];
// 将用户指定的规则转换成八位数组
for (int i = 0; i < byteTemp.length && i < keyByte.length; i++) {
byteTemp[i] = keyByte[i];
}
key = new SecretKeySpec(byteTemp, "DES");
return key.getEncoded();
}
public static String decryptDES(String decryptString, String decryptKey) throws Exception {
SecretKeySpec key = new SecretKeySpec(getKey(decryptKey), "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
byte decryptedData[] = cipher.doFinal(Base64Util.decodeMessage(decryptString));
return new String(decryptedData);
}

public static void main(String[] args) throws Exception {
String clearText = "cccccccc";  //这里的数据长度必须为8的倍数
String key = "12345678";
System.out.println("明文："+clearText+"\n密钥："+key);
String encryptText = encryptDES(clearText, key);
System.out.println("加密后："+encryptText);
String decryptText = decryptDES(encryptText, key);
System.out.println("解密后："+decryptText);
}
}



 */